/* 
 * Copyright 2006-2007 S W McIlroy
 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 * you may not use  this file  except in  compliance with the License.
 * You may obtain a copy of the License at 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed  under the  License is distributed on an "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 * implied.
 * 
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mockfu;

import static org.mockfu.Mocks.*;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.testng.annotations.Test;

public class FileSystemTest
{

    @Test
    public void test()
    throws Exception
    {
        /* create stub /etc/hosts input stream */
        StringBuilder hostsData = new StringBuilder();
        hostsData.append( "127.0.0.1 localhost\n" );
        hostsData.append( "10.0.0.1 faust.mockfu.org faust\n" );
        InputStream hostsInputStream = new ByteArrayInputStream( hostsData.toString().getBytes() );

        /* create a mock object that implements FileInputStream and delegates to our stub */
        MockControl<FileInputStream> hostsFileInputStream = MockControl.of( FileInputStream.class );
        hostsFileInputStream.allowsAnythingIn( InputStream.class );
        hostsFileInputStream.stubWithDelegate( hostsInputStream );

        /*
         * create an instance of the unit that substitutes calls to new
         * FileInputStream("/etc/hosts") with a reference to our mock object
         */
        UnitBuilder<HostsRepository> hostsBuilder = UnitBuilder.of( HostsRepository.class );
        hostsBuilder.replaceConstructor( FileInputStream.class, "/etc/hosts" )
                .with( hostsFileInputStream.mock() )
                .inMethod().getIpAddressFor( (String)null );
        HostsRepository unit = hostsBuilder.createUnit();

        /* exercise the unit and verify the result */
        assertThat( unit.getIpAddressFor( "faust" ), "10.0.0.1" );
        hostsInputStream.reset();
        assertThat( unit.getIpAddressFor( "localhost" ), "127.0.0.1" );
        hostsInputStream.reset();
        assertThat( unit.getIpAddressFor( "mephistopheles" ), null );
    }
    
    
    /**
     * The unit to test.
     */
    public static class HostsRepository
    {
        
        /**
         * Gets the IP address for a hostname in /etc/hosts.
         * 
         * @param hostname
         * @return
         */
        public String getIpAddressFor( String hostname )
        {
            try
            {
                FileInputStream fis = new FileInputStream( "/etc/hosts" );
                BufferedReader br = new BufferedReader( new InputStreamReader( fis ) );
                try
                {
                    for( String line ; (line = br.readLine()) != null ; )
                    {
                        String[] split = line.split( "\\s+" );
                        if( split[0].startsWith( "#" ) )
                            continue;
                        if( split.length > 1 && split[1].equals( hostname ) )
                            return split[0];
                        if( split.length > 2 && split[2].equals( hostname ) )
                            return split[0];
                    }
                }
                finally
                {
                    fis.close();
                }
            }
            catch( Exception ex )
            {
                throw new RuntimeException( ex );
            }
            return null;
        }
    }
    
}
